package web.controller;

import framework.vo.ResultInfo;
import framework.vo.ResultList;
import freemarker.template.TemplateException;
import net.xiaoboli.mgp.Gen;
import net.xiaoboli.mgp.GenData;
import net.xiaoboli.mgp.GenTableInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.SQLException;

@RestController
@RequestMapping("/gen")
public class GenController {

    @Autowired
    DataSource dataSource;

    @GetMapping("list")
    public ResultList<GenTableInfo> list() throws SQLException, TemplateException, IOException {
        try (Connection connection = dataSource.getConnection()) {
            Gen gen = new Gen(connection);
            return new ResultList<>(gen.list());
        }
    }

    @GetMapping("view")
    public void view(String table, String view, HttpServletResponse response) throws SQLException, TemplateException, IOException {

        if (StringUtils.isBlank(table)) {
            response.setStatus(400);
            response.getOutputStream().write("No input table ".getBytes(StandardCharsets.UTF_8));
            return;
        }

        if (StringUtils.isBlank(view)) {
            response.setStatus(400);
            response.getOutputStream().write("No input view ".getBytes(StandardCharsets.UTF_8));
            return;
        }

        if (view.startsWith(".")) {
            response.setStatus(400);
            response.getOutputStream().write("Input view illegality".getBytes(StandardCharsets.UTF_8));
            return;
        }

        if (view.startsWith("/")) {
            response.setStatus(400);
            response.getOutputStream().write("Input view illegality".getBytes(StandardCharsets.UTF_8));
            return;
        }

        try (Connection connection = dataSource.getConnection()) {
            Gen gen = new Gen(connection);
            gen.generator(response.getOutputStream(), table, view);
        }
    }

    @GetMapping("view.zip")
    public void viewZip(String table, String view, HttpServletResponse response) throws SQLException, IOException, TemplateException {

        if (StringUtils.isBlank(table)) {
            response.setStatus(400);
            response.getOutputStream().write("No input table ".getBytes(StandardCharsets.UTF_8));
            return;
        }

        if (StringUtils.isBlank(view)) {
            response.setStatus(400);
            response.getOutputStream().write("No input view ".getBytes(StandardCharsets.UTF_8));
            return;
        }

        if (view.startsWith(".")) {
            response.setStatus(400);
            response.getOutputStream().write("Input view illegality".getBytes(StandardCharsets.UTF_8));
            return;
        }

        if (view.startsWith("/")) {
            response.setStatus(400);
            response.getOutputStream().write("Input view illegality".getBytes(StandardCharsets.UTF_8));
            return;
        }

        try (Connection connection = dataSource.getConnection()) {
            Gen gen = new Gen(connection);
            response.setContentType("application/zip");
            response.setHeader("Content-disposition", "attachment; filename=" + table + ".zip");
            gen.zip(response.getOutputStream(), table, view.split(","));
        }

    }

    @GetMapping("view.json")
    public ResultInfo<GenData> viewJson(String table) throws SQLException, TemplateException, IOException {
        if (StringUtils.isBlank(table)) {
            return new ResultInfo<>().failed("No input table ");
        }
        try (Connection connection = dataSource.getConnection()) {
            Gen gen = new Gen(connection);
            GenData data = gen.data(table);
            return new ResultInfo<>(data);
        }
    }

}
